﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace OpenSees.XML
{
    /// <summary>
     /// 单元响应
     /// </summary>
    public class ElementResponse : Response
    {
        /// <summary>
        /// Recorder记录的分析结果
        /// </summary>
        private enum ResultType
        {
            /// <summary>
            /// 单元分析结果
            /// </summary>
            Element = 0,

            /// <summary>
            /// 截面分析结果
            /// </summary>
            FrameSection = 1,

            /// <summary>
            /// 材料分析结果
            /// </summary>
            Material = 2,

            /// <summary>
            /// 壳单元分析结果
            /// </summary>
            ShellSection = 3,

            /// <summary>
            /// 壳单元多维材料分析结果
            /// </summary>
            NdMaterial=4,

            /// <summary>
            /// 信息为空
            /// </summary>
            Empty = -1,
        }

        #region Properties

        /// <summary>
        /// 单元类型
        /// </summary>
        [XmlAttribute]
        public string eleType { set; get; }

        /// <summary>
        /// 单元编号
        /// </summary>
        [XmlAttribute]
        public int eleTag { set; get; }

        /// <summary>
        /// i端节点
        /// </summary>
        [XmlAttribute]
        public int node1 { set; get; }

        /// <summary>
        /// j端节点
        /// </summary>
        [XmlAttribute]
        public int node2 { set; get; }

        /// <summary>
        /// m端节点
        /// </summary>
        [XmlAttribute]
        public int node3 { set; get; }

        /// <summary>
        /// n端节点
        /// </summary>
        [XmlAttribute]
        public int node4 { set; get; }

        /// <summary>
        /// 高斯积分点分析结果
        /// </summary>
        [XmlElement("GaussPointOutput")]
        public GaussPrtXML GaussPointOutput { set; get; }

        /// <summary>
        /// 壳单元的高斯积分点响应
        /// </summary>
        [XmlElement("GaussPoint")]
        public List<GaussPrtXML> GaussPoint { set; get; }

        #endregion

        #region Variables

        [XmlIgnore]
        /// <summary>
        /// 获得分析结果
        /// </summary>
        /// <returns></returns>
        private ResultType GetResultType
        {
            get
            {
                //是否存在单元层次分析结果
                if (!this.isEmpty) return ResultType.Element;
                //是否存在截面、材料层次分析结果
                else if (this.GaussPointOutput != null && this.GaussPointOutput.SectionOutput != null)
                {
                    //获得截面
                    var section = this.GaussPointOutput.SectionOutput;
                    //截面层次分析结果
                    if (!section.isEmpty) return ResultType.FrameSection;
                    //材料层次分析结果
                    else if (this.GaussPointOutput.isFiberSectionValid())
                        return ResultType.Material;
                    //ND材料
                    else if (this.GaussPointOutput.NdMaterialOutput != null)
                        return ResultType.NdMaterial;
                }
                //是否存在壳单元层次分析结果
                if (this.GaussPoint != null && this.GaussPoint.Count != 0)
                {
                    foreach (var section in this.GaussPoint)
                    {
                        //壳单元层次分析结果
                        if ((section.SectionForceDeformation != null &&
                            !section.SectionForceDeformation.isEmpty) || (section.NdMaterialOutput != null &&
                            !section.NdMaterialOutput.isEmpty))
                            return ResultType.ShellSection;
                        else if (section.isFiberSectionValid())
                            return ResultType.NdMaterial;
                    }
                }
                return ResultType.Empty;
            }
        }

        [XmlIgnore]
        /// <summary>
        /// 是否反序列化完成
        /// </summary>
        public bool isObjectDeserialize
        {
            get
            {
                return this.GetResultType != ResultType.Empty;
            }
        }

        [XmlIgnore]
        /// <summary>
        /// 编号
        /// </summary>
        public override int ID
        {
            get
            {
                return this.eleTag;
            }
            set
            {

            }
        }

        #endregion

        /// <summary>
        /// 获得响应对象
        /// </summary>
        /// <returns></returns>
        public List<Response> GetResponses()
        {
            //枚举
            switch (this.GetResultType)
            {
                //单元层次分析结果
                case ResultType.Element: return new List<XML.Response> { this };
                //获得高斯积分点
                case ResultType.FrameSection:
                    this.GaussPointOutput.SetElementTag(this.eleTag);
                    return new List<XML.Response> { this.GaussPointOutput.SectionOutput };
                //材料响应
                case ResultType.Material:
                    this.GaussPointOutput.SetElementTag(this.eleTag);
                    return new List<XML.Response> { this.GaussPointOutput.GetFiberResponse() };
                //分层壳截面
                case ResultType.ShellSection:
                    //初始化
                    var responses = new List<Response>();
                    //遍历积分点
                    this.GaussPoint.ForEach(gaussPoint =>
                    {
                        if(gaussPoint.SectionForceDeformation != null &&
                            !gaussPoint.SectionForceDeformation.isEmpty)
                        {
                            gaussPoint.SectionForceDeformation.eleTag = this.eleTag;
                            gaussPoint.SectionForceDeformation.GaussPointID = gaussPoint.number;
                            responses.Add(gaussPoint.SectionForceDeformation);
                        }

                        if (gaussPoint.NdMaterialOutput != null &&
                            !gaussPoint.NdMaterialOutput.isEmpty)
                        {
                            gaussPoint.NdMaterialOutput.eleTag = this.eleTag;
                            gaussPoint.NdMaterialOutput.GaussPointID = gaussPoint.number;
                            responses.Add(gaussPoint.NdMaterialOutput);
                        }                            
                    });
                    return responses;
                case ResultType.NdMaterial:
                    {
                        //初始化
                        var ndMatResps = new List<Response>();
                        if (this.GaussPoint != null && this.GaussPoint.Count != 0)
                        {
                            //遍历积分点
                            this.GaussPoint.ForEach(gaussPoint =>
                            {
                                gaussPoint.SetElementTag(this.eleTag);
                                ndMatResps.Add(gaussPoint.GetFiberResponse());
                            });
                        }
                        else if (this.GaussPointOutput != null)
                        {
                            this.GaussPointOutput.SetElementTag(this.eleTag);
                            ndMatResps.Add(this.GaussPointOutput.NdMaterialOutput);
                        }
                        return ndMatResps;
                    }

                    
                //未知
                case ResultType.Empty:
                default:  return null;
            }
        }

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public ElementResponse()
        {

        }
    }


}
